package com.hhkj.admin.sale.service.biz.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import com.hhkj.admin.common.event.EventPublisher;
import com.hhkj.admin.order.common.cont.OrderConst;
import com.hhkj.admin.order.domain.OrderItem;
import com.hhkj.admin.question.common.utils.QuestionImportTemplateUtils;
import com.hhkj.admin.sale.common.cont.SaleConst;
import com.hhkj.admin.sale.common.utils.InvitationQRCodeUtils;
import com.hhkj.admin.sale.common.utils.SaleLevelUtils;
import com.hhkj.admin.sale.common.utils.SaleNumUtils;
import com.hhkj.admin.sale.domain.Sale;
import com.hhkj.admin.sale.event.SaleInitializingEvent;
import com.hhkj.admin.sale.model.dopo.SaleDo;
import com.hhkj.admin.sale.model.dopo.SaleManagementPo;
import com.hhkj.admin.sale.model.dopo.SalePo;
import com.hhkj.admin.sale.model.req.SaleReq;
import com.hhkj.admin.sale.model.res.SaleManagementRes;
import com.hhkj.admin.sale.model.res.SaleRes;
import com.hhkj.admin.sale.service.base.SaleAccountService;
import com.hhkj.admin.sale.service.base.SaleService;
import com.hhkj.admin.sale.service.biz.SaleBizService;
import com.hhkj.admin.sale.service.extend.SaleExtendService;
import com.ruoyi.common.base.biz.service.biz.BaseBizServiceImpl;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.excl.model.ExcelCreateModel;
import com.ruoyi.common.utils.excl.utils.ExcelUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SaleBizServiceImpl extends BaseBizServiceImpl<Sale, SaleReq, SaleRes, SaleDo, SalePo, SaleService, SaleExtendService> implements SaleBizService {

    @Autowired
    private EventPublisher eventPublisher;

    @Autowired
    private SaleAccountService saleAccountService;

    @Override
    protected void beforeUpdate(SaleReq saleReq) {
        if (SaleConst.TypeEnum.ROOT.getCode().equals(saleReq.getTypeCode())) {
            // 判断身份证号是否已经存在
            String idCard = saleReq.getIdCard();
            if (StringUtils.isBlank(idCard)) {
                throw new GlobalException("身份证号不能为空");
            }
            if (isIdCardExist(idCard)) {
                throw new GlobalException("该身份证号已被注册，请重新输入");
            }
        }
        super.beforeUpdate(saleReq);
    }

    @Override
    protected void beforeSave(SaleReq saleReq) {
        saleReq.setRegisterTime(new Date());
        eventPublisher.sendEvent(new SaleInitializingEvent(saleReq));
        super.beforeSave(saleReq);
    }

    @Override
    protected void afterSave(SaleReq saleReq) {
        saleAccountService.initAccount(saleReq.getId());
        super.afterSave(saleReq);
    }

    @Override
    public boolean reset(Long id) {
        Sale sale = this.getService().getById(id);
        if (sale.getTypeCode().equals(SaleConst.TypeEnum.ROOT.getCode()) == false) {
            throw new GlobalException("只有销售才能重置密码");
        }
        SaleReq saleReq = BeanUtil.toBean(sale, SaleReq.class);
        encodingPassword(saleReq);
        return this.getService().updateById(saleReq);
    }

    @Override
    public void encodingPassword(SaleReq saleReq) {
        String mobile = saleReq.getMobile();
        if (mobile.length() < SaleConst.PASSWORD_NUM) {
            throw new GlobalException("手机号长度过短");
        }
        String password = mobile.substring(mobile.length() - SaleConst.PASSWORD_NUM);
        saleReq.setPassword(SecurityUtils.encryptPassword(password));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveSaleRoot(SaleReq saleReq) {
        // 判断身份证号是否已经存在
        String idCard = saleReq.getIdCard();
        if (StringUtils.isBlank(idCard)) {
            throw new GlobalException("身份证号不能为空");
        }
        if (isIdCardExist(idCard)) {
            throw new GlobalException("该身份证号已被注册，请重新输入");
        }
        if(IdcardUtil.isValidCard(idCard) == false) {
            throw new GlobalException("身份证号码格式不正确");
        }
        if (isMobileExist(saleReq.getMobile())) {
            throw new GlobalException("改手机号已经被注册，请重新输入");
        }
        //生成编号
        SaleReq condition = new SaleReq();
        condition.setTypeCode(SaleConst.TypeEnum.ROOT.getCode());
        long rootSaleAmount = getService().countByDo(condition);
        String rootLevel = SaleLevelUtils.getRootLevel();
        String num = SaleNumUtils.generate(rootLevel, rootSaleAmount);
        saleReq.setNum(num);
        saleReq.setLevel(rootLevel);
        saleReq.setTypeCode(SaleConst.TypeEnum.ROOT.getCode());
        return this.save(saleReq);
    }

    @Override
    public List<SaleManagementRes> listForManagement(SaleReq saleReq) {
        List<SaleManagementPo> salePoList = this.getService().listForManagement(saleReq);
        List<SaleManagementRes> saleResList = BeanUtil.copyToList(salePoList, SaleManagementRes.class);
        return saleResList;
    }

    @Override
    public boolean updateDisabledFlag(SaleReq saleReq) {
        Sale sale = getExtendService().getByIdNotNull(saleReq.getId());
        if (SaleConst.TypeEnum.SALE.getCode().equals(sale.getTypeCode()) == false) {
            throw new GlobalException("只能禁用商家，不可禁用销售");
        }
        sale.setDisabledFlag(saleReq.getDisabledFlag());
        return getService().updateById(sale);
    }

    @Override
    public Workbook createSaleManagementExportExcel(SaleReq saleReq) {
        List<SaleManagementRes> saleResList = listForManagement(saleReq);
        String titleSuffix = "";
        if (ObjectUtil.isNotEmpty(saleReq.getDateStart()) && ObjectUtil.isNotEmpty(saleReq.getDateEnd())) {
            titleSuffix = " 时间范围："
                    + DateUtil.format(saleReq.getDateStart(), "yyyy-MM-dd")
                    + " 到 " +
                    DateUtil.format(saleReq.getDateEnd(), "yyyy-MM-dd");
        }
        Workbook template = ExcelUtils.createExcelWorkbookSheetNumber(new ExcelCreateModel(
                SaleConst.SALE_MANAGEMENT_EXPORT_TITLE,
                SaleConst.SALE_MANAGEMENT_EXPORT_TITLE + titleSuffix,
                saleResList,
                SaleManagementRes.class));
        return template;
    }

    @Override
    public boolean isMobileExist(String mobile) {
        SaleDo condition = new SaleDo();
        condition.setMobile(mobile);
        Sale sale = getService().getPoByDo(condition);
        return ObjectUtil.isNotEmpty(sale);
    }

    @Override
    public boolean isIdCardExist(String idCard) {
        SaleDo condition = new SaleDo();
        condition.setIdCard(idCard);
        Sale sale = getService().getPoByDo(condition);
        return ObjectUtil.isNotEmpty(sale);
    }

    @EventListener
    @Order(1)
    public void encodingPassword(SaleInitializingEvent saleInitializingEvent) {
        encodingPassword((SaleReq) saleInitializingEvent.getSource());
    }

    @EventListener
    @Order(2)
    public void generateInvitationQRCode(SaleInitializingEvent saleInitializingEvent) {
        SaleReq saleReq = (SaleReq) saleInitializingEvent.getSource();
        String url = InvitationQRCodeUtils.generateAliYunUrl(saleReq.getNum());
        saleReq.setInvitationCodeUrl(url);
    }


}
